<!-- 该组件现在仅支持无规格的设备，后期可扩展 -->
<script setup lang="ts">
  import { useGetNotSpecGoodList } from '@/services/pages/good/useGood'
  import { computed, nextTick, PropType, ref, watch } from 'vue'
  import {
    ElTable,
    ElTableColumn,
    ElRadioGroup,
    ElRadio,
    ElSelect,
    ElOption,
    ElInput,
    ElIcon,
    TableInstance,
    ElTree,
  } from 'element-plus'
  import Pagination from '@/components/Pagination/index.vue'
  import { useGetAllGoodTypeOptions } from '@/services/pages/good/useType'
  import { useGetBrandOptions } from '@/services/pages/good/useBrand'
  import { Search, RefreshRight } from '@element-plus/icons-vue'
  import _ from 'lodash'

  const {
    options: goodTypeOptions,
    getOptionsLoading: getGoodTypeOptionsLoading,
    getOptions: getGoodTypeOptions,
  } = useGetAllGoodTypeOptions()
  const {
    options: brandOptions,
    loading: getBrandOptionsLoading,
    getBrandOptionsParam,
    getBrandOptions,
  } = useGetBrandOptions()
  const {
    goodList: notSpecGoodList,
    listTotal: notSpecGoodListTotal,
    getGoodListParam: getNotSpecGoodListParam,
    getGoodListLoading: getNotSpecGoodListLoading,
    getGoodList: getNotSpecGoodList,
  } = useGetNotSpecGoodList()

  /**
   * mode - 设备选择弹窗组件的类型
   * manual: 说明书的设备选择
   * onlineVideo: 在线视频的设备选择
   */
  const props = defineProps({
    type: {
      type: String as PropType<'manual' | 'onlineVideo'>,
      default: () => 'manual',
    },
    goodSelectList: {
      type: Array as PropType<Array<NotSpecGoodListItem>>,
      default: () => [],
    },
  })

  const emits = defineEmits<{
    (e: 'select-good', value: typeof _goodList.value): void
  }>()

  // 获取列表请求参数
  const _getGoodListParam = ref<GoodAPIRequest.GetNotSpecGoodList>({
    limit: 50,
    page: 1,
    brandId: '',
    typeId: '',
    typeThreeId: '',
    typeTwoId: '',
    goodsType: 1,
    keyword: '',
  })

  // 抽屉显示状态
  const visible = defineModel('visible', { type: Boolean, default: false })

  // 表格组件实例
  const tableInstance = ref<TableInstance | null>(null)

  // 加载
  const loading = computed(() => {
    return getNotSpecGoodListLoading.value || getGoodTypeOptionsLoading.value
  })

  // 设备列表分页组件实例
  const goodListPaginationInstance = ref<InstanceType<typeof Pagination> | null>(null)

  // 设备列表
  const _goodList = computed<Array<NotSpecGoodListItem>>(() => {
    if (['manual', 'onlineVideo'].includes(props.type)) {
      return notSpecGoodList.value
    }
    return []
  })

  // 设备列表总条数
  const _goodListTotal = computed(() => {
    if (['manual', 'onlineVideo'].includes(props.type)) {
      return notSpecGoodListTotal.value
    }
    return 0
  })

  // 设备选择列表
  const _goodSelectList = ref<Array<NotSpecGoodListItem>>([])

  // 设备分类属性组件参数
  const goodTypeTreeProps = {
    children: 'childData',
    label: 'name',
    disabled: 'disabled',
  }

  // 选中的分类id
  const selectedTypeId = ref('')

  /**
   * 获取设备分类
   */
  const getTypes = async () => {
    await getGoodTypeOptions()
    goodTypeOptions.value.unshift({
      disabled: false,
      id: '',
      name: '全部',
      select: true,
      childData: [],
      level: 1,
    })
  }

  /**
   * 从选择列表中寻找指定的设备
   * @param {String} id - 设备id
   */
  const findGoodIndexFromSelectList = (id: string) => {
    return _goodSelectList.value.findIndex((good) => id === good.id)
  }

  /**
   * 设备选择项变化时触发，用于添加设备
   * @param {Array} goods - 设备列表
   */
  const handleGoodSelectionChange = (goods: Array<NotSpecGoodListItem>) => {
    goods.forEach((item) => {
      if (findGoodIndexFromSelectList(item.id) === -1) {
        _goodSelectList.value.push(item)
      }
    })
  }

  /**
   * 用户手动勾选选择项时触发，用于移除设备
   * @param {Array} goods - 设备列表
   * @param good - 设备对象
   */
  const handleGoodSelect = (goods: Array<NotSpecGoodListItem>, good: NotSpecGoodListItem) => {
    const isGoodSelect = goods.some((item) => item.id === good.id)
    if (!isGoodSelect) {
      const index = findGoodIndexFromSelectList(good.id)
      if (index >= 0) {
        _goodSelectList.value.splice(index, 1)
      }
    }
  }

  /**
   * 用户全选时触发，用于移除全部设备
   * @param {Array} goods - 设备列表
   */
  const handleGoodSelectAll = (goods: Array<NotSpecGoodListItem>) => {
    if (goods.length <= 0) {
      _goodList.value.forEach((item) => {
        const index = findGoodIndexFromSelectList(item.id)
        if (index >= 0) {
          _goodSelectList.value.splice(index, 1)
        }
      })
    }
  }

  /**
   * 获取设备列表
   */
  const _getGoodList = () => {
    nextTick(async () => {
      if (goodListPaginationInstance.value) {
        _getGoodListParam.value.limit = goodListPaginationInstance.value.size
        _getGoodListParam.value.page = goodListPaginationInstance.value.current
        if (['manual', 'onlineVideo'].includes(props.type)) {
          getNotSpecGoodListParam.value = {
            limit: _getGoodListParam.value.limit,
            page: _getGoodListParam.value.page,
            typeId: _getGoodListParam.value.typeId,
            typeTwoId: _getGoodListParam.value.typeTwoId,
            typeThreeId: _getGoodListParam.value.typeThreeId,
            brandId: _getGoodListParam.value.brandId,
            goodsType: _getGoodListParam.value.goodsType,
            keyword: _getGoodListParam.value.keyword,
          }
          await getNotSpecGoodList()
        }
        goodEcho()
      }
    })
  }

  /**
   * 分类点击事件
   * @param {GoodTypeOptions} type - 分类id
   */
  const handleTypeClick = (type: GoodTypeOptions) => {
    selectedTypeId.value = type.id
    _getGoodListParam.value = {
      limit: 50,
      page: 1,
      typeId: type.level === 1 ? type.id : '',
      typeTwoId: type.level === 2 ? type.id : '',
      typeThreeId: type.level === 3 ? type.id : '',
      brandId: '',
      goodsType: 1,
      keyword: '',
    }
    _getGoodList()
  }

  /**
   * 隐藏抽屉
   */
  const hideDrawer = () => {
    visible.value = false
  }

  /**
   * 重置事件
   */
  const handleClearSearchFilter = () => {
    const typeId = _getGoodListParam.value.typeId
    const goodType = _getGoodListParam.value.goodsType
    _getGoodListParam.value = {
      limit: 50,
      page: 1,
      typeId: typeId,
      typeTwoId: '',
      typeThreeId: '',
      brandId: '',
      goodsType: goodType,
      keyword: '',
    }
    _getGoodList()
  }

  /**
   * 品牌下拉搜索事件
   * @param {String} keyword - 搜索关键字
   */
  const handleGetBrandOptions = _.debounce((keyword: string) => {
    if (getBrandOptionsParam.value.name !== keyword) {
      getBrandOptionsParam.value.name = keyword
      getBrandOptions()
    }
  })

  /**
   * 确定事件
   */
  const onConfirm = () => {
    emits('select-good', _.cloneDeep(_goodSelectList.value))
    hideDrawer()
  }

  /**
   * 设备回显
   */
  const goodEcho = () => {
    nextTick(() => {
      if (tableInstance.value) {
        _goodSelectList.value.forEach((item) => {
          const selectGood = _goodList.value.find((good) => good.id === item.id)
          if (selectGood) {
            tableInstance.value.toggleRowSelection(selectGood, true)
          }
        })
      }
    })
  }

  watch(
    visible,
    (value) => {
      if (value) {
        _goodSelectList.value = props.goodSelectList
        getBrandOptions()
        _getGoodList()
        getTypes()
      }
    },
    { immediate: true },
  )
</script>

<template>
  <h-drawer
    v-model="visible"
    title="选择设备"
    :loading="loading"
    :width="1200"
    unit="px"
    @close="hideDrawer"
  >
    <div class="good-select-modal-wrapper">
      <div class="classify-list-container">
        <div class="title">设备分类</div>
        <div class="classify-wrapper">
          <template v-if="!['manual', 'onlineVideo'].includes(props.type)">
            <el-radio-group v-model="_getGoodListParam.goodsType" size="small">
              <el-radio :value="1">成品</el-radio>
              <el-radio :value="2">物料</el-radio>
            </el-radio-group>
          </template>
          <div class="classify-list">
            <el-tree
              :data="goodTypeOptions"
              :props="goodTypeTreeProps"
              node-key="id"
              @node-click="handleTypeClick"
            >
              <template #default="{ node, data }">
                <div
                  :class="{
                    'active-classify': selectedTypeId === data.id,
                  }"
                >
                  <h-tooltip-text :text="node.label" :height="28" :max-width="200"></h-tooltip-text>
                </div>
              </template>
            </el-tree>
          </div>
        </div>
      </div>
      <div class="list-container">
        <div class="header">
          <div class="title"> 设备列表 </div>
          <div class="search">
            <el-select
              v-model="_getGoodListParam.brandId"
              placeholder="请选择品牌"
              :loading="getBrandOptionsLoading"
              filterable
              clearable
              :filter-method="handleGetBrandOptions"
              @change="_getGoodList"
              @clear="_getGoodList"
            >
              <el-option
                v-for="(brand, brandIndex) in brandOptions"
                :key="brandIndex"
                :label="brand.name"
                :disabled="brand.disabled"
                :value="brand.id"
              ></el-option>
            </el-select>
            <el-input
              v-model.trim="_getGoodListParam.keyword"
              placeholder="请输入设备名称/型号/序列号"
              clearable
              @keyup.enter="_getGoodList"
              @clear="_getGoodList"
            ></el-input>
            <h-button type="primary" @click="_getGoodList">
              <el-icon>
                <Search />
              </el-icon>
              搜素
            </h-button>
            <h-button @click="handleClearSearchFilter">
              <el-icon>
                <RefreshRight></RefreshRight>
              </el-icon>
              重置
            </h-button>
          </div>
        </div>
        <div class="table">
          <el-table
            ref="tableInstance"
            :border="true"
            stripe
            :data="_goodList"
            height="100%"
            @selection-change="handleGoodSelectionChange"
            @select="handleGoodSelect"
            @select-all="handleGoodSelectAll"
          >
            <!-- 序号 -->
            <el-table-column
              type="selection"
              width="50"
              fixed="left"
              :align="'center'"
            ></el-table-column>

            <!-- 序号 -->
            <el-table-column
              type="index"
              label="序号"
              width="50"
              fixed="left"
              :align="'center'"
            ></el-table-column>

            <!-- 编号 -->
            <el-table-column label="编号" width="180" prop="code"></el-table-column>

            <!-- 品牌 -->
            <el-table-column
              label="品牌"
              width="100"
              prop="brand"
              show-overflow-tooltip
            ></el-table-column>

            <!-- 设备名称 -->
            <el-table-column
              label="设备名称"
              min-width="140"
              prop="name"
              show-overflow-tooltip
            ></el-table-column>

            <!-- 型号 -->
            <el-table-column
              label="型号"
              width="140"
              prop="model"
              show-overflow-tooltip
            ></el-table-column>

            <!-- 质保时间（天） -->
            <el-table-column
              label="质保时间（天）"
              width="120"
              prop="warrantyDay"
            ></el-table-column>
          </el-table>
        </div>
        <div class="pagination">
          <pagination
            ref="goodListPaginationInstance"
            :list_total="_goodListTotal"
            @current-change="_getGoodList"
            @size-change="_getGoodList"
          ></pagination>
        </div>
      </div>
    </div>
    <template #footer>
      <h-button is-modal type="primary" @click="onConfirm">确定</h-button>
      <h-button is-modal @click="hideDrawer">取消</h-button>
    </template>
  </h-drawer>
</template>

<style scoped lang="scss">
  .good-select-modal-wrapper {
    display: flex;
    column-gap: 12px;
    height: 100%;

    .classify-list-container {
      width: 300px;
      height: 100%;
      display: flex;
      flex-direction: column;
      row-gap: 5px;

      .title {
        font-size: 14px;
        height: 28px;
        line-height: 28px;
      }

      .classify-wrapper {
        border: 1px solid #e5e5e5;
        box-sizing: border-box;
        padding: 0 12px;
        height: calc(100% - 68px);
        overflow: auto;

        :deep(.el-radio-group) {
          width: 100%;
          height: 40px;
          column-gap: 12px;
          box-sizing: border-box;
          padding-left: 12px;
          border-bottom: 1px solid #e5e5e5;
        }

        .classify-list {
          padding: 6px 0 6px 0;
          box-sizing: border-box;
          display: flex;
          flex-direction: column;
          row-gap: 4px;

          .classify-item {
            width: 100%;
            height: 28px;
            list-style: none;
            box-sizing: border-box;
            // padding: 0 14px;
            cursor: pointer;
            display: flex;
            align-items: center;
          }

          .classify-item-active {
            background-color: rgba(0, 123, 255, 0.137254902) !important;
            color: #007cff;
          }

          :deep(.el-tree) {
            .el-tree-node {
              .el-tree-node__content {
                height: 28px !important;
              }
            }

            .el-tree-node {
              .el-tree-node__content:has(.active-classify) {
                color: #fff !important;
                background-color: $primaryColor;

                .el-tree-node__expand-icon {
                  color: #fff !important;
                }
              }
            }
          }
        }
      }
    }

    .list-container {
      flex: 1;
      width: 0;
      display: flex;
      flex-direction: column;
      row-gap: 5px;

      .header {
        display: flex;
        justify-content: space-between;

        .title {
          height: 28px;
          line-height: 28px;
          font-size: 14px;
        }

        .search {
          display: flex;
          column-gap: 5px;

          :deep(.el-select) {
            width: 120px;
          }

          :deep(.el-input) {
            width: 180px;
          }
        }
      }

      .table {
        max-height: calc(100% - 68px);
      }

      .pagination {
        display: flex;
        justify-content: flex-end;
      }
    }
  }
</style>
